#ifndef _GEOMETRY_H
#define _GEOMETRY_H

#include "GlobalDefines.h"
class Geometry
{
public:
	Geometry(){};
	virtual ~Geometry(){};
	virtual void ReadGeometry(char* GeoName,emx::Real3D Shift) = 0;
protected:
	std::ifstream fin;
};

class TriangleMesh:public Geometry
{
protected:
	struct node{
		emx::Real3D Position;
		int Idx;
	};
	struct facet{
		blitz::TinyVector<node*,3> Vertex;
		emx::real_data Area;
		emx::Real3D Center, Normal;
		int Idx;
	};
	struct edge{
		emx::real_data EdgeLength;
		node *BeginVertex, *EndVertex;
		facet *LeftFacet, *RightFacet;
		emx::Real3D T_plus, T_minus;
		int Idx;
	};
public:
	TriangleMesh(emx::MediumType medium):Medium(medium){};
	virtual ~TriangleMesh(){};
	void ReadGeometry(char* GeoName,emx::Real3D Shift);
	const int GetEdgeNum() const{return Edge_Num;}
	const node* GetNode(const int Idx) const{return Node(Idx);}
	const edge* GetEdge(const int Idx) const{return Edge(Idx);}
	const facet* GetPatch(const int Idx) const{return Patch(Idx);}
	const emx::MediumType GetMedium() const{return Medium;}
	virtual void Initial() = 0;
protected:
	bool ReadNodes(emx::Real3D Shift);
	bool ReadPatchs();
	bool ReadEdges();
protected:
	emx::MediumType Medium;
	int Node_Num, Patch_Num, Edge_Num;
	blitz::Array<node*, 1> Node;			
	blitz::Array<edge*, 1> Edge;
	blitz::Array<facet*, 1> Patch;
public:
	emx::zVector I;
};

//Equivalent Surface
class EquivalentSurface:public TriangleMesh
{
public:
	EquivalentSurface():TriangleMesh(emx::Vaccum){};
	EquivalentSurface(emx::MediumType medium):TriangleMesh(medium){};
	virtual ~EquivalentSurface(){};
	virtual void Initial();
};

//PEC Object or Uniform Dielectric
class Object:public TriangleMesh
{
public:
	Object():TriangleMesh(emx::PEC){};
	Object(emx::MediumType medium):TriangleMesh(medium){};
	virtual ~Object(){};
	virtual void Initial();
};

#endif